import { AnimationAction } from "../../thirdparty/three/imports";
import { animationActionLoopStylesNames, animationActionLoopStylesValues } from "../../thirdparty/three/polyfills/constants/AnimationActionLoopStyles";
import { AnimationClip3D } from "./AnimationClip3D";

export class AnimationAction3D
{
    _animationAction: AnimationAction;

    get enabled()
    {
        return this._animationAction.enabled;
    }
    set enabled(v)
    {
        this._animationAction.enabled = v;
    }

    get paused()
    {
        return this._animationAction.paused;
    }
    set paused(v)
    {
        this._animationAction.paused = v;
    }

    get time()
    {
        return this._animationAction.time;
    }
    set time(v)
    {
        this._animationAction.time = v;
    }

    get clampWhenFinished()
    {
        return this._animationAction.clampWhenFinished;
    }
    set clampWhenFinished(v)
    {
        this._animationAction.clampWhenFinished = v;
    }

    get loop()
    {
        return animationActionLoopStylesNames[this._animationAction.loop];
    }
    set loop(v)
    {
        this._animationAction.loop = animationActionLoopStylesValues[v];
    }

    setEffectiveTimeScale(timeScale: number)
    {
        const animationAction = this._animationAction.setEffectiveTimeScale(timeScale);

        return AnimationAction3D.get(animationAction);
    }

    setEffectiveWeight(weight: number)
    {
        const animationAction = this._animationAction.setEffectiveWeight(weight);

        return AnimationAction3D.get(animationAction);
    }

    play()
    {
        this._animationAction.play();

        return this;
    }

    stop()
    {
        this._animationAction.stop();

        return this;
    }

    reset()
    {
        this._animationAction.reset();

        return this;
    }

    getClip()
    {
        const animationClip = this._animationAction.getClip();

        const result = new AnimationClip3D();
        result._animationClip = animationClip;

        return result;
    }

    getEffectiveWeight()
    {
        const Weight = this._animationAction.getEffectiveWeight();

        return Weight;
    }

    crossFadeTo(fadeInAction: AnimationAction3D, duration: number, warp: boolean)
    {
        const animationAction = this._animationAction.crossFadeTo(fadeInAction._animationAction, duration, warp);

        return AnimationAction3D.get(animationAction);
    }

    fadeIn(duration: number)
    {
        const animationAction = this._animationAction.fadeIn(duration);

        return AnimationAction3D.get(animationAction);
    }

    fadeOut(duration: number)
    {
        const animationAction = this._animationAction.fadeOut(duration);

        return AnimationAction3D.get(animationAction);
    }

    static get(action: AnimationAction)
    {
        let result = this._cache.get(action);

        if (!result)
        {
            result = new AnimationAction3D();
            result._animationAction = action;
            this._cache.set(action, result);
        }

        return result;
    }

    private static _cache = new Map<AnimationAction, AnimationAction3D>();
}
